﻿/*=========================================================================
 * AUTH: Matthew Baum, 9753095
 * DATE: April-09-2012
 * LAST: April-09-2012
 * DESC: Defines an enemy spawn location for the game.
 *=========================================================================*/

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace RisingThreat
{
    class SpawnPoint
    {
        // CONST limit for the number of enemies that can spawn from a point
        public const byte MAX_SPAWN_COUNT = 10;

        // CONST time interval for spawning enemies
        private const float SPAWN_INTERVAL = 5.0f;

        // CONST: required distance from player (to spawn)
        private const float MIN_SPAWN_DIST = 15.0f;

        // Time elapsed since last spawn
        private double elapsedSpawnTime = 0;
        
        // Location
        private Vector3 position;

        // List of enemies
        private Enemy[] enemies = new Enemy[MAX_SPAWN_COUNT];

        // CONSTRUCTOR
        public SpawnPoint(float xPos, float zPos, Model mod, List<Teammate> teammates, Player player, LevelGraph graph)
        {
            position = new Vector3(xPos, 0, zPos);

            // INIT enemy list
            initEnemies(mod, teammates, player, graph);
        }

        // Fill array with new enemies
        private void initEnemies(Model mod, List<Teammate> teammates, Player player, LevelGraph graph)
        {
            for(int i = 0; i != enemies.Length; ++i)
            {
                enemies[i] = new Enemy
                (
                    mod,
                    position,
                    teammates,
                    player,
                    graph
                );
            }
        }

        // Spawn an enemy
        public void spawn()
        {
            // Spawn a new enemy at THIS position
            foreach(Enemy enemy in enemies)
            {
                if (enemy.isAlive == false)
                {
                    // Set alive
                    enemy.isAlive = true;

                    // Set at spawn point
                    enemy.steer.position = this.position;

                    // BREAK
                    break;
                }
            }
        }

        // UPDATE
        public void update(TimeSpan elapsedTime, Player player)
        {
            // Update spawn time
            elapsedSpawnTime += elapsedTime.TotalSeconds;

            int count = getActiveCount();

            // IF max spawn count is NOT reached
            if (count < MAX_SPAWN_COUNT)
            {
                // IF enough time elapsed
                if (elapsedSpawnTime >= SPAWN_INTERVAL)
                {
                    // Reset elapsed time
                    elapsedSpawnTime = 0;

                    // IF Player is far enough
                    float dist = (player.steer.position - this.position).Length();

                    if (dist >= MIN_SPAWN_DIST)
                    {
                        // Spawn an enemy
                        spawn();
                    }
                }
            }
        }

        // PRIVATE HELPER to count active enemies
        private int getActiveCount()
        {
            // Count of active enemies
            int activeCount = 0;

            for (int i = 0; i != enemies.Length; ++i)
            {
                if (enemies[i].isAlive)
                {
                    ++activeCount;
                }
            }

            // Return count
            return activeCount;
        }

        // GET position
        public Vector3 getPosition()
        {
            return position;
        }

        // GET enemies from this point
        public Enemy[] getEnemies()
        {
            return enemies;
        }

        // RESET this spawn point
        public void reset()
        {
            // Reset enemies
            foreach (Enemy enemy in enemies)
            {
                enemy.isAlive = false;
            }

            // Reset timer
            elapsedSpawnTime = 0;
        }
    }
}
